#!/bin/bash
#
# Download and install EmulationStation themes for Batocera
#
# @lbrpdx on Batocera Forums and Discord
#
# Usage:
# batocera-es-theme 'list' or 'install <theme>'
#
# If you don't provide a <theme>, the list of themes available online will be returned back to you
#
ARCH="$(cat /storage/.config/.OS_ARCH)"
if [ "${ARCH}" == "RG351P" ]; then
  DEVICE="RG351P"
elif [ "${ARCH}" == "RG351V" ]; then
  DEVICE="RG351V"
elif [ "${ARCH}" == "RG351MP" ]; then
  DEVICE="RG351MP"
elif [ "${ARCH}" == "RG552" ]; then
  DEVICE="RG552"
fi
CONFIGDIR="/storage/.emulationstation/themes"
THEMESLIST="https://raw.githubusercontent.com/AmberELEC/metadata/main/${DEVICE}/themes.cfg"
LOCALTHEMESLIST="/storage/.config/distribution/configs/themes.txt"
# themes.txt must be a plain file with the format 'theme_name https://githubURL' (spaces or tabs)
# Example of a themes.txt file:
#  fundamental	https://github.com/jdorigao/es-theme-fundamental
#  Zoid		https://github.com/RetroPie/es-theme-zoid

###############################
#
function usage() {
	echo "$0 - downloads and installs EmulationStation themes for Batocera"
	echo " "
	echo "It accepts two modes: 'list' and 'install <theme>'"
	echo "- 'list' for the list of themes available online, and if they are"
	echo "   [A]vailable to install, [I]nstalled or [?]unknown."
	echo "- 'install <theme>' to install the theme, from its theme name."
	echo "- 'remove <theme>' to delete an installed theme."
	echo " "
	echo "If you have a local $LOCALTHEMESLIST file,"
	echo "it will override the one hosted on Batocera website."
	exit 1
}

###############################
#
function check_url() {
	[[ "$1" =~ ^(https?|ftp)://.*$ ]] && echo "[A]" || echo "[?]"
}

###############################
#
function git_name() {
	echo "$1" | sed "s,.*/\(.*\),\1,"
}

###############################
#
function repo_name() {
	echo "$1" | sed "s,.*github.com/\([A-Za-z0-9_-]*\)/.*,\1,"
}

###############################
#
function list_themes() {
	fn=$(date +"%s")
	tmp="/tmp/themes_$fn"
	echo "* Batocera themes *"
	if [ -f $LOCALTHEMESLIST ]; then
		cp -f "$LOCALTHEMESLIST" "$tmp"
	else
		curl -H 'Cache-Control: no-cache' -sfL "$THEMESLIST" -o "$tmp" || exit 1
		sed -i 's/\r$//' "${tmp}"
	fi
	while IFS=$' \t' read name url ; do
		[ x"$name" == "x" ] && continue
		ia=$(check_url "$url")
		gitname=$(git_name "$url")
		[ -d "$CONFIGDIR"/"$gitname" ] && ia="[I]"
		echo "$ia $name - $url"
	done < "$tmp"
	[[ -e "$tmp" ]] && rm "$tmp"
}


###############################
#
function getPer() {
	TARFILE="$1"
	TARVAL="$2"
	while true; do
		CURVAL=$(stat "$TARFILE" | grep -E '^[ ]*Size:' | sed -e s+'^[ ]*Size: \([0-9][0-9]*\) .*$'+'\1'+)
		CURVAL=$((CURVAL / 1024 / 1024))
		PER=$((${CURVAL} * 100 / ${TARVAL}))
		echo "${PER}% - ${theme^^} - [${TARVAL}MB]"
		sleep 2
	done
}

###############################
#
function install_theme() {
	theme="$1"
	success_installed=0
	fn=$(date +"%s")
	tmp="/tmp/themes_$fn"
	if [ -f $LOCALTHEMESLIST ]; then
		cp -f "$LOCALTHEMESLIST" "$tmp"
	else
		curl -H 'Cache-Control: no-cache' -sfL "$THEMESLIST" -o "$tmp" || exit 1
		sed -i 's/\r$//' "${tmp}"
	fi
	while IFS=$' \t' read name url ; do
		[ x"$name" != x"$theme" ] && continue
		ia=$(check_url "$url")
		if [ x"$ia" != x"[A]" ]; then
			echo "Error - invalid theme URL $url"
			exit 1
		else
			reponame=$(repo_name "$url")
			gitname=$(git_name "$url")
			cd "$CONFIGDIR"
                        branch=$(curl -H 'Cache-Control: no-cache' -L "https://api.github.com/repos/$reponame/$gitname" 2>/dev/null| grep -m1 "default_branch" | sed -e 's#^.*: "##' -e 's#",.*$##')
                        filezip="${url}/archive/${branch}.zip"
			# get size to download (hack to get it from github)
			size=$(curl -H 'Cache-Control: no-cache' -sfL "https://api.github.com/repos/$reponame/$gitname" 2>/dev/null| grep size | head -1 | tr -dc '[:digit:]')
			size=$((size / 1024 ))
			test $? -eq 0 || exit 1
			touch "$gitname.zip"
			getPer "$CONFIGDIR"/"$gitname.zip" "${size}" &
			GETPERPID=$!
			curl -H 'Cache-Control: no-cache' -sfL "${filezip}" -o "$gitname.zip" || exit 1
			kill -9 "${GETPERPID}" >/dev/null 2>/dev/null
			GETPERPID=
			if [ -f "$gitname.zip" ]; then
				echo "Unzipping $gitname theme files >>> 99%"
				if [ -d "$CONFIGDIR/$gitname" ]
				then
					rm -rf "$CONFIGDIR/$gitname"
				fi
				unzip "$gitname.zip" >/dev/null 2>&1
				mv "$gitname-${branch}" "$gitname"
				rm "$gitname.zip"
				success_installed=1
			else
				echo "Error - $theme zip file could not be downloaded from $url"
				exit 1
			fi
		fi
	done < "$tmp"
	[[ -e "$tmp" ]] && rm "$tmp"
	if [ "$success_installed" == 1 ]; then
		echo "Theme $theme is now installed >>> 100%"
		exit 0
	else
		echo "Error - theme $theme could not be found"
		exit 1
	fi
}

###############################
#
function remove_theme() {
        theme="$1"
        success_removed=0
        fn=$(date +"%s")
        tmp="/tmp/themes_$fn"
        if [ -f $LOCALTHEMESLIST ]; then
                cp -f "$LOCALTHEMESLIST" "$tmp"
        else
                curl -sfL "$THEMESLIST" -o "$tmp" || exit 1
        fi
        while IFS=$' \t' read name url ; do
                [ x"$name" != x"$theme" ] && continue
				#There are some weird control characters we need to strip
				url=$(echo -n "${url//[[:space:]]/}")
                gitname=$(git_name "$url")
                if [ -d "$CONFIGDIR"/"$gitname" ]; then
                        rm -rf "$CONFIGDIR"/"$gitname" && success_removed=1
                else
                        echo "Theme $theme doesn't appear to be in $CONFIGDIR/$gitname"
                fi
        done < "$tmp"
        rm "$tmp"
        if [ "$success_removed" == 1 ]; then
                echo "Theme ${theme^^} is now removed >>>100"
                exit 0
        else
                echo "Error - theme $theme could not be removed"
                exit 1
        fi
}

#### Main loop
#
command="$1"
theme="$2"

if ! [ -d "$CONFIGDIR" ]; then
	echo "Error - theme directory $CONFIGDIR is not valid."
	exit 1
fi
if [ x"$command" == "xlist" ]; then
	list_themes
elif [ x"$command" == "xinstall" ]; then
	[ x"$theme" != "x" ] && install_theme $theme || usage
elif [ x"$command" == "xremove" ]; then
	[ x"$theme" != "x" ] && remove_theme $theme || usage
else
	usage
fi
